package com.wan37.logic.tradingshop.handler;

import com.wan37.common.uuid.UUIDUtil;
import com.wan37.logic.backpack.weaponry.WeaponryManager;
import com.wan37.logic.component.LogicWorkerHandlerCenter;
import com.wan37.logic.component.Worker;
import com.wan37.logic.db.AsynDBManager;
import com.wan37.logic.domain.Result;
import com.wan37.logic.domain.entity.UserDO;
import com.wan37.logic.domain.entity.UserItemDO;
import com.wan37.logic.domain.vo.BackpackVO;
import com.wan37.logic.domain.vo.ItemVO;
import com.wan37.logic.domain.vo.MessageVO;
import com.wan37.logic.domain.vo.WeaponryVO;
import com.wan37.logic.email.EmailManager;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.handler.MsgHandler;
import com.wan37.logic.service.UserItemService;
import com.wan37.logic.service.UserService;
import com.wan37.logic.service.UserWeaponryService;
import com.wan37.logic.service.cache.ItemServiceCache;
import com.wan37.logic.service.cache.UserServiceCache;
import com.wan37.logic.tradingshop.TradingShopManager;
import com.wan37.logic.tradingshop.cache.TradingShopCache;
import com.wan37.logic.tradingshop.domain.vo.TradingShopRecordVO;
import com.wan37.logic.tradingshop.domain.vo.TradingShopVO;
import com.wan37.logic.tradingshop.service.TradingShopRecordService;
import com.wan37.logic.tradingshop.service.TradingShopService;
import com.wan37.logic.tradingshop.util.TradingShopRouteUtil;
import com.wan37.logic.utils.DelayDequeThreadPollUtil;
import com.wan37.protobuf.constant.BackpackLabel;
import com.wan37.protobuf.constant.CommonTradingShop;
import com.wan37.protobuf.constant.ShopLabel;
import com.wan37.protobuf.constant.TradingShopLabel;
import com.wan37.protobuf.message.client2server.game.GameTradingShop;

/**
 * @author : luoyong
 * @date : 2020-08-05 11:00
 **/
public class CGameTradingShopHandler extends MsgHandler {
    private TradingShopService tradingShopService;
    private TradingShopRecordService tradingShopRecordService;
    private TradingShopCache tradingShopCache;
    private TradingShopRouteUtil tradingShopRouteUtil;
    private AsynDBManager asynDBManager;
    private UserServiceCache userServiceCache;
    private UserService userService;
    private EmailManager emailManager;
    private ItemServiceCache itemServiceCache;
    private UserItemService userItemService;
    private DelayDequeThreadPollUtil delayDequeThreadPollUtil;
    private TradingShopManager tradingShopManager;
    private UserWeaponryService userWeaponryService;
    private LogicWorkerHandlerCenter logicWorkerHandlerCenter;

    /**
     * MsgHandler构造函数
     *
     * @param messageVO
     */
    public CGameTradingShopHandler(MessageVO messageVO) {
        super(messageVO);
        this.tradingShopService = SpringContextHolder.getBean("tradingShopService");
        this.tradingShopRecordService = SpringContextHolder.getBean("tradingShopRecordService");
        this.tradingShopCache = SpringContextHolder.getBean("tradingShopCache");
        this.tradingShopRouteUtil = SpringContextHolder.getBean("tradingShopRouteUtil");
        this.asynDBManager = SpringContextHolder.getBean("asynDBManager");
        this.userServiceCache = SpringContextHolder.getBean("userServiceCache");
        this.userService = SpringContextHolder.getBean("userService");
        this.emailManager = SpringContextHolder.getBean("emailManager");
        this.itemServiceCache = SpringContextHolder.getBean("itemServiceCache");
        this.userItemService = SpringContextHolder.getBean("userItemService");
        this.delayDequeThreadPollUtil = SpringContextHolder.getBean("delayDequeThreadPollUtil");
        this.tradingShopManager = SpringContextHolder.getBean("tradingShopManager");
        this.userWeaponryService = SpringContextHolder.getBean("userWeaponryService");
        this.logicWorkerHandlerCenter = SpringContextHolder.getBean("logicWorkerHandlerCenter");
    }

    @Override
    public void execute(Worker worker) throws Exception {
        GameTradingShop.TradingShopMsg tradingShopMsg = (GameTradingShop.TradingShopMsg) messageVO.getMessage();
        int code = tradingShopMsg.getCode();
        String userId = messageVO.getUserId();
        switch (code) {
            case CommonTradingShop.GET_ALL:
                tradingShopManager.getAll(userId);
                break;
            case CommonTradingShop.ADD_AUCTION:
            case CommonTradingShop.ADD_FIXED_PRICE:
                TradingShopVO tradingShopVO = new TradingShopVO(tradingShopMsg.getTradingShop());
                tradingShopVO.setCreateTime(System.currentTimeMillis());
                TradingShopCache.TradingShopIn tradingShopIn = tradingShopCache.new TradingShopIn();
                tradingShopIn.setTradingShopVO(tradingShopVO);
                tradingShopCache.getTradingShopInMap().put(tradingShopVO.getTradingShopId(), tradingShopIn);
                if (tradingShopVO.getTradingShopType() == TradingShopLabel.AUCTION) {
                    delayDequeThreadPollUtil.updateTimeSchedule(TradingShopLabel.AUCTION_TIME, "",
                            tradingShopVO.getTradingShopId(), new AuctionResultHandler(tradingShopVO.getTradingShopId()));
                }
                //上架的物品需要从自己物品缓存和数据库中删除！
                if (tradingShopVO.getType() == BackpackLabel.WEAPONRY) {
                    asynDBManager.distributeWork(userId,
                            () -> userWeaponryService.deleteBySelfWeaponryId(tradingShopMsg.getString()));
                    userServiceCache.getUserServiceMap()
                            .get(userId).getWeaponryVOMap().remove(tradingShopMsg.getString());
                }
                asynDBManager.distributeWork(userId, () -> tradingShopService.save(tradingShopVO));
                tradingShopRouteUtil.sendTradingShopResponse(code, "上架成功！", userId, tradingShopVO);
                break;
            case CommonTradingShop.BUY_FIXED_PRICE:
                TradingShopVO tradingShopVO1 = new TradingShopVO(tradingShopMsg.getTradingShop());
                Result result = null;
                if (tradingShopVO1.getType() == BackpackLabel.WEAPONRY) {
                    result = buyFixedPriceWeaponry(userId, tradingShopVO1);
                } else if (tradingShopVO1.getType() == BackpackLabel.ITEM) {
                    result = buyFixedPriceItem(userId, tradingShopVO1);
                } else if (tradingShopVO1.getType() == ShopLabel.MONEY_TYPE_GOLD) {

                }
                if (result.getCode() == 0) {
                    tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR, result.getContent(), userId);
                }
                break;
            case CommonTradingShop.BUY_AUCTION:
                TradingShopVO tradingShopVO2 = new TradingShopVO(tradingShopMsg.getTradingShop());
                Result result1 = null;
                if (tradingShopVO2.getType() == BackpackLabel.WEAPONRY) {
                    result1 = buyAuctionWeaponry(userId, tradingShopVO2,
                            new TradingShopRecordVO(tradingShopMsg.getTradingShopRecord()));
                } else if (tradingShopVO2.getType() == BackpackLabel.ITEM) {

                } else if (tradingShopVO2.getType() == ShopLabel.MONEY_TYPE_GOLD) {

                }
                if (result1.getCode() == 0) {
                    tradingShopRouteUtil.sendTradingShopResponse(CommonTradingShop.ERROR, result1.getContent(), userId);
                }
                break;
            case CommonTradingShop.GET_USER_ALL_BUY_RECORD:
                tradingShopRouteUtil.sendTradingShopResponse(code, userId, null, tradingShopRecordService.findByBuyId(userId));
                break;
            case CommonTradingShop.GET_USER_ALL_USER_ID_RECORD:
                tradingShopRouteUtil.sendTradingShopResponse(code, userId, null, tradingShopRecordService.findByUserId(userId));
                break;
            default:
                break;
        }
    }

    /**
     * 出价装备拍品
     *
     * @param userId
     * @param tradingShopVO
     * @param tradingShopRecordVO
     * @return
     */
    private Result buyAuctionWeaponry(String userId, TradingShopVO tradingShopVO, TradingShopRecordVO tradingShopRecordVO) {
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        if (user.getUserVO().getIngot() < tradingShopVO.getIngot()
                || user.getUserVO().getIngot() < tradingShopRecordVO.getIngot()) {
            return new Result(0, "元宝不足！");
        }
        if (!tradingShopCache.getTradingShopInMap().containsKey(tradingShopVO.getTradingShopId())) {
            return new Result(0, "竞拍已经结束！");
        }
        logicWorkerHandlerCenter.distributeWork(tradingShopVO.getTradingShopId(),
                new AuctionUserBuyHandler(tradingShopRecordVO, userId));
        return new Result(1, "");
    }

    /**
     * 竞拍一口价装备
     *
     * @param userId
     * @param tradingShopVO
     * @return
     */
    private Result buyFixedPriceWeaponry(String userId, TradingShopVO tradingShopVO) {
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        if (user.getUserVO().getIngot() < tradingShopVO.getIngot()) {
            return new Result(0, "元宝不足！");
        }
        if (!tradingShopCache.getTradingShopInMap().containsKey(tradingShopVO.getTradingShopId())) {
            return new Result(0, "你手慢了哦，已经别另一个金主爸爸买走了哦！");
        }
        //处理自身元宝扣除
        user.getUserVO().setIngot(user.getUserVO().getIngot() - tradingShopVO.getIngot());
        UserDO userDO = new UserDO(user.getUserVO());
        asynDBManager.distributeWork(userId, () -> userService.update(userDO));
        logicWorkerHandlerCenter.distributeWork(tradingShopVO.getTradingShopId(),
                new FixedPriceResultHandler(tradingShopVO.getTradingShopId(), userId, tradingShopVO.getIngot()));
        return new Result(1, "竞拍成功，物品已发邮箱！！");
    }

    private Result buyFixedPriceItem(String userId, TradingShopVO tradingShopVO) {
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        if (user.getUserVO().getIngot() < tradingShopVO.getIngot()) {
            return new Result(0, "元宝不足！");
        }
        if (!tradingShopCache.getTradingShopInMap().containsKey(tradingShopVO.getTradingShopId())) {
            return new Result(0, "你手慢了哦，已经别另一个金主爸爸买走了哦！");
        }
        //处理自身元宝扣除
        user.getUserVO().setIngot(user.getUserVO().getIngot() - tradingShopVO.getIngot());
        asynDBManager.distributeWork(userId, () -> userService.update(new UserDO(user.getUserVO())));

        ItemVO itemVO = userServiceCache.getUserServiceMap().get(userId).getItemVOMap().get(tradingShopVO.getBackpackId());
        if (itemVO == null) {
            itemVO = itemServiceCache.getItemServiceMap().get(tradingShopVO.getBackpackId()).getItemVO();
            if (itemVO.getCount() == null) {
                itemVO.setCount(tradingShopVO.getCount());
            } else {
                itemVO.setCount(itemVO.getCount() + tradingShopVO.getCount());
            }
            UserItemDO userItemDO = new UserItemDO();
            userItemDO.setUserId(userId);
            userItemDO.setItemId(itemVO.getBackpackId());
            userItemDO.setCount(itemVO.getCount());
            asynDBManager.distributeWork(userId, () -> userItemService.save(userItemDO));
        } else {
            itemVO.setCount(itemVO.getCount() + tradingShopVO.getCount());
            UserItemDO userItemDO = new UserItemDO();
            userItemDO.setUserId(userId);
            userItemDO.setItemId(itemVO.getBackpackId());
            userItemDO.setCount(itemVO.getCount());
            asynDBManager.distributeWork(userId, () -> userItemService.update(userItemDO));
        }
        return new Result(1, "购买成功！");
    }
}
